package org.xxpay.pay.ctrl.payment;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.xxpay.core.common.constant.MchConstant;
import org.xxpay.core.common.domain.api.AbstractRes;
import org.xxpay.core.common.domain.api.ApiBuilder;
import org.xxpay.core.common.domain.api.SettQueryRes;
import org.xxpay.core.common.util.MyLog;
import org.xxpay.core.common.util.XXPayUtil;
import org.xxpay.core.entity.MchInfo;
import org.xxpay.core.entity.SettRecord;
import org.xxpay.pay.ctrl.common.BaseController;
import org.xxpay.pay.service.SettOrderService;

import javax.servlet.http.HttpServletRequest;

/**
 * @Description: 结算订单查询
 * @author zhux
 * @date 2018-11-26
 * @version V1.0
 * @Copyright: www.xxpay.org
 */
@RestController(value = "/api/sett/query_sett")
public class QuerySettController extends BaseController {
    private final MyLog _log = MyLog.getLog(QuerySettController.class);

    @Autowired
    private SettOrderService settOrderService;

    /**
     * 查询结算订单接口:
     * 1)先验证接口参数以及签名信息
     * 2)根据参数查询订单
     * 3)返回订单数据
     * @param request
     * @return
     */
    @RequestMapping(value = "/api/sett/query_sett")
    public AbstractRes querySettOrder(HttpServletRequest request) {
        _log.info("###### 开始接收商户查询结算订单请求 ######");
        String logPrefix = "【商户结算订单查询】";
        try{
            JSONObject po = getJsonParam(request);
            JSONObject settContext = new JSONObject();
            // 验证参数有效性
            String errorMessage = validateParams(po, settContext);
            if (!"success".equalsIgnoreCase(errorMessage)) {
                _log.warn(errorMessage);
                return ApiBuilder.bizError(errorMessage);
            }
            _log.debug("请求参数及签名校验通过");
            Long infoId = po.getLong("infoId"); 			        // 商户ID
            String mchOrderNo = po.getString("mchOrderNo"); 	        // 结算订单号
            SettRecord settRecord = settOrderService.query(infoId, mchOrderNo);
            _log.info("{}查询结算订单,结果:{}", logPrefix, settRecord);
            if (settRecord == null) {
                return ApiBuilder.bizError("结算订单不存在");
            }

            SettQueryRes settQueryRes = ApiBuilder.buildSuccess(SettQueryRes.class);
            settQueryRes.setBySettRecord(settRecord);
            settQueryRes.autoGenSign(settContext.getString("key")); //自动签名
            _log.info("###### 商户查询结算订单处理完成 ######");
            return settQueryRes;
        }catch (Exception e){
            _log.error(e, "");
            return ApiBuilder.bizError("结算系统异常");
        }
    }


    /**
     * 验证创建订单请求参数,参数通过返回JSONObject对象,否则返回错误文本信息
     * @param params
     * @return
     */
    private String validateParams(JSONObject params, JSONObject settContext) {

        //验证公共请求参数
        String commonErrorMsg = super.validateCommonParams(params);
        if(commonErrorMsg != null) return commonErrorMsg;

        // 验证请求参数,参数有问题返回错误提示
        String errorMessage;
        // 结算订单参数
        String infoId = params.getString("infoId"); 			                         // 商户ID
        String mchOrderNo = params.getString("mchOrderNo"); 			// 结算订单号
        String sign = params.getString("sign"); 				                        // 签名

        // 验证请求参数有效性（必选项）
        Long infoIdL;
        if(StringUtils.isBlank(infoId) || !NumberUtils.isDigits(infoId)) {
            errorMessage = "request params[infoId] error.";
            return errorMessage;
        }
        infoIdL = Long.parseLong(infoId);

        if(StringUtils.isBlank(mchOrderNo)) {
            errorMessage = "request params[mchOrderNo] error.";
            return errorMessage;
        }

        // 签名信息
        if (StringUtils.isEmpty(sign)) {
            errorMessage = "request params[sign] error.";
            return errorMessage;
        }

        // 查询商户信息
        MchInfo mchInfo = commonService.mchInfoService.findByMchId(infoIdL);
        if(mchInfo == null) {
            errorMessage = "Can't found mchInfo[infoId="+infoId+"] record in db.";
            return errorMessage;
        }
        if(mchInfo.getStatus() != MchConstant.PUB_YES) {
            errorMessage = "mchInfo not available [infoId="+infoId+"] record in db.";
            return errorMessage;
        }

        String key = mchInfo.getPrivateKey();
        if (StringUtils.isBlank(key)) {
            errorMessage = "key is null[infoId="+infoId+"] record in db.";
            return errorMessage;
        }
        settContext.put("key", key);

        // 验证签名数据
        boolean verifyFlag = XXPayUtil.verifyPaySign(params, key);
        if(!verifyFlag) {
            errorMessage = "Verify XX sett sign failed.";
            return errorMessage;
        }

        return "success";
    }

}
